# -*- coding:UTF-8 -*-
import time

import serial
from RPi import GPIO

from raspberryPi.Constant import enTLEFT, enTRIGHT, enSTOP, Buzzer, Run_car, enRUN, Back_car, enBACK, Left_car, enLEFT, \
    Right_car, enRIGHT, Stop_car


def whistle():
    """
    小车鸣笛
    :return:
    """
    GPIO.output(Buzzer, GPIO.LOW)
    time.sleep(0.1)
    GPIO.output(Buzzer, GPIO.HIGH)
    time.sleep(0.001)


class Serial:
    def __init__(self, ultrasonicAvoid, infraredAvoid, track, steering):
        self.ser = serial.Serial("/dev/ttyAMA0", 9600, timeout=0.001)
        print "serial.isOpen() = ", self.ser.isOpen()

        GPIO.setup(Buzzer, GPIO.OUT, initial=GPIO.HIGH)

        self.ReturnTemp = ''
        self.g_CarState = 0
        self.CarSpeedControl = 50
        self.NewLineReceived = 0
        self.InputString = ''
        self.InputStringCache = ''
        self.StartBit = 0
        self.NewLineReceived = 0

        self.ultrasonicAvoid = ultrasonicAvoid
        self.infraredAvoid = infraredAvoid
        self.track = track
        self.steering = steering

    def serialEvent(self):
        """
        串口事件
        :return: None
        """
        self.InputString = ''
        while True:
            size = self.ser.inWaiting()
            if size == 0:
                break
            else:
                while size != 0:
                    serialDataBit = self.ser.read(1)
                    size -= 1
                    if serialDataBit == '$':
                        self.StartBit = 1
                    if self.StartBit == 1:
                        self.InputStringCache += serialDataBit
                    if self.StartBit == 1 and serialDataBit == '#':
                        self.NewLineReceived = 1
                        self.InputString = self.InputStringCache
                        self.InputStringCache = ''
                        self.StartBit = 0
                        size = 0

    def serial_data_postback(self):
        """
        采集的传感器数据串口回发给上位机显示
        打包格式如:
            超声波  电压   灰度   巡线  红外避障 寻光
        $4WD,CSB120,PV8.3,GS214,LF1011,HW11,GM11#
        :return: None
        """
        self.ReturnTemp = ''
        distance = self.ultrasonicAvoid.getDistance()
        # 超声波
        self.ReturnTemp += "$4WD,CSB"
        self.ReturnTemp += str(int(distance))
        self.ReturnTemp += ",PV8.4"
        self.ReturnTemp += ",GS0"
        # 巡线
        self.ReturnTemp += ",LF"
        self.track.trackLine()
        self.ReturnTemp += self.track.infrared_track_value
        # 红外
        self.ReturnTemp += ",HW"
        self.infraredAvoid.getDistance()
        self.ReturnTemp += self.infraredAvoid.infrared_avoid_value

        # 无用功能模块
        self.ReturnTemp += ",GM"
        LDR_value_list = ['0', '0']
        LDR_value = ''.join(LDR_value_list)
        self.ReturnTemp += LDR_value

        self.ReturnTemp += "#"
        self.ser.write(self.ReturnTemp)

    def serial_data_parse(self):
        """
        串口数据解析并指定相应的动作
        解析上位机发来的舵机云台的控制指令并执行舵机旋转
        如:$4WD,PTZ180# 舵机转动到180度
        :return:
        """
        if self.InputString.find("$4WD,PTZ", 0, len(self.InputString)) != -1:
            i_1 = self.InputString.find("PTZ", 0, len(self.InputString))
            i_2 = self.InputString.find("#", 0, len(self.InputString))
            if i_2 > i_1:
                m_kp = int(self.InputString[i_1 + 3:i_2])
                self.steering.servo_control(180 - m_kp)
                self.NewLineReceived = 0
                self.InputString.zfill(len(self.InputString))

        # 解析上位机发来的通用协议指令,并执行相应的动作
        # 如:$1,0,0,0,0,0,0,0,0,0#    小车前进
        if (self.InputString.find("$4WD", 0, len(self.InputString)) == -1) and \
                (self.InputString.find("#", 0, len(self.InputString)) != -1):
            if self.InputString[3] == '1':
                self.g_CarState = enTLEFT
            elif self.InputString[3] == '2':
                self.g_CarState = enTRIGHT
            else:
                self.g_CarState = enSTOP
            if self.InputString[5] == '1':
                whistle()
            if self.InputString[7] == '1':
                self.CarSpeedControl += 20
            if self.CarSpeedControl > 100:
                self.CarSpeedControl = 100
            if self.InputString[7] == '2':
                self.CarSpeedControl -= 20
            if self.CarSpeedControl < 20:
                self.CarSpeedControl = 20
            if self.InputString[9] == '1':
                self.steering.servo_control(180)
            if self.InputString[9] == '2':
                self.steering.servo_control(0)

            if self.InputString[17] == '1':
                self.steering.servo_control(90)

            if self.g_CarState != enTLEFT and self.g_CarState != enTRIGHT:
                if self.InputString[1] == Run_car:
                    self.g_CarState = enRUN
                elif self.InputString[1] == Back_car:
                    self.g_CarState = enBACK
                elif self.InputString[1] == Left_car:
                    self.g_CarState = enLEFT
                elif self.InputString[1] == Right_car:
                    self.g_CarState = enRIGHT
                elif self.InputString[1] == Stop_car:
                    self.g_CarState = enSTOP
                else:
                    self.g_CarState = enSTOP
            self.NewLineReceived = 0
            self.InputString.zfill(len(self.InputString))
